#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include "SpinLock.cpp"

const unsigned NN = 4000000, THREADS = 20;
unsigned val1 = 0, val2 = 0;
SpinLock lock;

void *increment_unsafe(void *param){
	for(unsigned i=0; i<NN; i++) val1+=1;
	pthread_exit(NULL);
}

void *increment_safe(void *param){
	for(unsigned i=0; i<NN; i++){
		lock.get();
		val2+=1;
		lock.release();
	}
	pthread_exit(NULL);
}

int main(){
	unsigned i;
	
	pthread_t unsafeThreads[THREADS], safeThreads[THREADS];
	for(i=0; i<THREADS; i++){
		pthread_create(unsafeThreads+i, NULL, increment_unsafe, NULL);
		pthread_create(safeThreads+i, NULL, increment_safe, NULL);
	}

	sleep(60);
	
	for(i=0; i<THREADS; i++){
		pthread_join(unsafeThreads[i], NULL);
		pthread_join(safeThreads[i], NULL);
	}

	std::cout << val1 << "\t(without spinlock)" << std::endl;
	std::cout << THREADS*NN << "\t(actual value)" << std::endl;
	std::cout << val2 << "\t(with spinlock)" << std::endl;
}

